﻿Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports Microsoft.DirectX.AudioVideoPlayback

''' <summary>
''' Lässt einen Kommandanten einen oder mehrere Sätze sprechen.
''' </summary>
''' <remarks></remarks>
Public Class ObjektKOTextZeile
    Const KOBildBreite As Integer = 48
    Const TextRand As Integer = 10
    Const HintergrundsBildBreite As Integer = 320
    Enum KOGesichtsAusdruck
        ''' <summary>
        ''' Sieh doch morgens mal in den Spiegel dann weißt du was ich meine
        ''' </summary>
        ''' <remarks></remarks>
        Normal
        ''' <summary>
        ''' Du gewinnst 1 Fantastiliarden. Dann guckst du auch so!:D
        ''' </summary>
        ''' <remarks></remarks>
        Lachend
        ''' <summary>
        ''' So sieht es aus wenn man verliert
        ''' </summary>
        ''' <remarks></remarks>
        Traurig
    End Enum
    Dim Gesichtsausdruck As KOGesichtsAusdruck = KOGesichtsAusdruck.Normal
    Dim Text As ObjektText
    Dim KOID As Integer = 0
    Dim ZusatzRand As Integer = 0
    Structure SprechBlaße
        Public Sub New(ByVal Zeile12 As String, ByVal Zeile22 As String)
            Me.Zeile1 = Zeile12
            Me.Zeile2 = Zeile22
        End Sub
        Dim Zeile1 As String
        Dim Zeile2 As String
        Public Function GetSprechBlaße() As String()
            Return New String() {Zeile1, Zeile2}
        End Function
    End Structure
    Dim TextOrt As Integer = 0
    Dim TextBlaßen() As SprechBlaße = {}
    Dim YOrt As Integer
    Public Sub ChangeYOrt(ByVal Change As Integer)
        YOrt += Change
        Text.YStart += Change
    End Sub
    Public Function GetYOrt()
        Return YOrt
    End Function
    Dim Hintergrundstextur As Texture
    Dim MaxWarteZeit As Integer = -1
    Dim Frame As Integer = 0

    Public Sub New(ByVal KOID As String, ByVal neuText As String, ByVal Gesichtsausdruck As KOGesichtsAusdruck, ByVal Y As Integer, ByVal MaxWarteZeit As Integer, ByVal Spieler As Integer)
        Dim ID As Integer = 0
        For I = 0 To Objektverwalter.KOS.Length - 1
            If KOID = Objektverwalter.KOS(I).KOID Then
                ID = I
                Exit For
            End If
        Next
        Laden(ID, neuText, Gesichtsausdruck, Y, MaxWarteZeit, Spieler)
        AddHandles()
    End Sub
    Public Sub New(ByVal KOID As Integer, ByVal neuText As String, ByVal Gesichtsausdruck As KOGesichtsAusdruck, ByVal Y As Integer, ByVal MaxWarteZeit As Integer, ByVal Spieler As Integer)
        Laden(KOID, neuText, Gesichtsausdruck, Y, MaxWarteZeit, Spieler)
        AddHandles()
    End Sub

    Public Sub Laden(ByVal KOID As Integer, ByVal neuText As String, ByVal Gesichtsausdruck As KOGesichtsAusdruck, ByVal Y As Integer, ByVal MaxWarteZeit As Integer, ByVal Spieler As Integer)
        Me.KOID = KOID
        If Me.Text Is Nothing Then
            Me.Text = New ObjektText(New String() {}, 0, 0, Nothing, "Courier New", 10, FontStyle.Regular, True, 2)
        End If
        Me.Gesichtsausdruck = Gesichtsausdruck
        ReDim TextBlaßen(-1)
        SplitText(neuText)
        YOrt = Y
        Me.MaxWarteZeit = MaxWarteZeit
        If Objektverwalter.Spielfeld Is Nothing Then
            Hintergrundstextur = Grafikengine.LoadTexture(Image.FromFile(My.Settings.Resourcenpfad + "Objekte\Dialogfeld.PNG"), Hauptmenü.Farbtabelleerstellen(Hauptmenü.AlleFarbtabellen(Spieler)))
        ElseIf Spieler > Objektverwalter.Spielfeld.Spieler.Length - 1 Then
            Hintergrundstextur = Grafikengine.LoadTexture(Image.FromFile(My.Settings.Resourcenpfad + "Objekte\Dialogfeld.PNG"), Hauptmenü.Farbtabelleerstellen(Hauptmenü.AlleFarbtabellen(Spieler)))
        Else
            Hintergrundstextur = Grafikengine.LoadTexture(Image.FromFile(My.Settings.Resourcenpfad + "Objekte\Dialogfeld.PNG"), Hauptmenü.Farbtabelleerstellen(Objektverwalter.Spielfeld.Spieler(Spieler).Farbe))
        End If
        TextOrt = 0
        Text.neuerText(TextBlaßen(0).GetSprechBlaße, ZusatzRand + TextRand + KOBildBreite, YOrt + 2, Nothing, True, 3)
    End Sub
    ''' <summary>
    ''' Splittet den Text so das er immer auf den Bildschirm passt.
    ''' </summary>
    ''' <param name="neuText"></param>
    ''' <remarks></remarks>
    Private Sub SplitText(ByVal neuText As String)
        'So ich hoffe ich erwische hier eine einigermaßen Clevere Methode.
        'Da wir eine Schrift wählen, wo alle Buchstaben gleich groß sind. können wir die Sache so lösen
        Dim Buchstabenbreite As Integer = Me.Text.GetSchriftart.MeasureString(Schriftengine.Sprite2, "A", Microsoft.DirectX.Direct3D.DrawTextFormat.None, Color.Black).Width
        'Wir berechnen wie viel Platz wir für den Text haben.
        Dim Breite As Integer = Hauptmenü.MainMenü.MalPanel.Width - TextRand * 2 - KOBildBreite
        'Wir berechnen wie viele Buchstaben Maximal Platz haben
        Dim BuchstabenZahl As Integer = Math.DivRem(Breite, Buchstabenbreite, ZusatzRand)
        ZusatzRand = ZusatzRand / 2
        Dim Buchstaben() As Char = neuText.ToCharArray()
        If Buchstaben.Length <= BuchstabenZahl Then
            'Wie praktisch der Text ist so klein er passt auf jeden Fall in eine Zeile
            AddSprechBlaße(neuText, "")
        Else
            Dim LetztesZeichen As Integer = 0

            Dim Zeile1 As String = ""
            Dim Zeile2 As String = ""
            Do
                For I = BuchstabenZahl To 0 Step -1
                    If I + LetztesZeichen < Buchstaben.Length Then
                        If Buchstaben(I + LetztesZeichen) = " " Then
                            Dim C(I - 1) As Char
                            For I2 = 0 To C.Length - 1
                                C(I2) = Buchstaben(LetztesZeichen + I2)
                            Next
                            If Zeile1 = "" Then
                                Zeile1 = CStr(C)
                            Else
                                Zeile2 = CStr(C)
                            End If
                            LetztesZeichen += I + 1
                            Exit For
                        ElseIf I = 0 Then
                            Dim C(BuchstabenZahl - 1) As Char
                            For I2 = 0 To C.Length - 1
                                C(I2) = Buchstaben(LetztesZeichen + I2)
                            Next
                            If Zeile1 = "" Then
                                Zeile1 = CStr(C)
                            Else
                                Zeile2 = CStr(C)
                            End If
                            LetztesZeichen += BuchstabenZahl + 1
                            Exit For
                        End If
                    Else
                        Exit Do
                    End If
                Next
                If Not Zeile1 = "" And Not Zeile2 = "" Then
                    AddSprechBlaße(Zeile1, Zeile2)
                    Zeile1 = ""
                    Zeile2 = ""
                End If
            Loop While Buchstaben.Length - LetztesZeichen >= BuchstabenZahl
            Dim C1(Buchstaben.Length - LetztesZeichen - 1) As Char
            For I2 = 0 To C1.Length - 1
                C1(I2) = Buchstaben(LetztesZeichen + I2)
            Next
            If Zeile1 = "" Then
                Zeile1 = CStr(C1)
            Else
                Zeile2 = CStr(C1)
            End If
            AddSprechBlaße(Zeile1, Zeile2)
        End If
    End Sub

    Public Function Malen() As Boolean
        Dim sngRotation As Double = 0
        Dim intColor As Color = Color.FromArgb(255, 255, 255, 255)
        If ObjektKODialog.DialogHintergrundsbild IsNot Nothing Then
            With Grafikengine.recBild
                .X = 0
                .Y = 0
                .Width = ObjektKODialog.DialogHintergrundsbildBreite
                .Height = ObjektKODialog.DialogHintergrundsbildHöhe
            End With
            Grafikengine.ptfRotCenter = Nothing
            Grafikengine.szfScale = Nothing
            Grafikengine.ptfPosition = New Drawing.Point(0, 0)
            Grafikengine.Sprite.Draw2D(ObjektKODialog.DialogHintergrundsbild, Grafikengine.recBild, New Size(Hauptmenü.MainMenü.MalPanel.Width, Hauptmenü.MainMenü.MalPanel.Height - 50), Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
        End If
        With Grafikengine.recBild
            .X = 0
            .Y = 0
            .Width = HintergrundsBildBreite
            .Height = 50
        End With
        Grafikengine.ptfRotCenter = Nothing
        Grafikengine.szfScale = Nothing
        Dim Max As Integer = Hauptmenü.MainMenü.MalPanel.Width / HintergrundsBildBreite + 1
        For I = 0 To Max
            Grafikengine.ptfPosition = New Drawing.Point(HintergrundsBildBreite * I, YOrt)
            Grafikengine.Sprite.Draw2D(Hintergrundstextur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
        Next
        With Grafikengine.recBild
            .X = 48 * Gesichtsausdruck
            .Y = 350
            .Width = KOBildBreite
            .Height = KOBildBreite
        End With
        Grafikengine.ptfPosition = New Drawing.Point(ZusatzRand / 2, YOrt + 1)
        Grafikengine.Sprite.Draw2D(Objektverwalter.KOS(KOID).KOTextur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
        Grafikengine.Sprite.End()
        Schriftengine.Sprite2.Begin(SpriteFlags.AlphaBlend)
        If Text.Malen(Schriftengine.Sprite2) = False Then
            'Der Text ist Fertig geschrieben
            If Frames() = True Then
                If TextOrt >= TextBlaßen.Length Then
                    Schriftengine.Sprite2.End()
                    Grafikengine.Sprite.Begin(SpriteFlags.AlphaBlend)
                    RemoveHandles()
                    Return True
                Else
                    Text.neuerText(TextBlaßen(TextOrt).GetSprechBlaße, ZusatzRand + TextRand + KOBildBreite, YOrt + 2, Nothing, True, 3)
                End If
            End If
        End If
        Schriftengine.Sprite2.End()
        Grafikengine.Sprite.Begin(SpriteFlags.AlphaBlend)
        Return False
    End Function

    Private Function Frames() As Boolean
        Frame += 1
        If Frame >= MaxWarteZeit And MaxWarteZeit >= 0 Then
            TextOrt += 1
            Return True
        Else
            Return False
        End If

    End Function

    Private Sub AddSprechBlaße(ByVal Zeile1 As String, ByVal Zeile2 As String)
        Array.Resize(TextBlaßen, TextBlaßen.Length + 1)
        TextBlaßen(TextBlaßen.Length - 1) = New SprechBlaße(Zeile1, Zeile2)
    End Sub

    Public Sub MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
        If Now < ObjektKODialog.WarteZeit Then Exit Sub
        Select Case e.Button
            Case MouseButtons.Left
                If Text.IsGeschrieben Then
                    If TextOrt = TextBlaßen.Length - 1 Then
                        'Jetzt wird der Text beendet
                        MaxWarteZeit = 1
                    Else
                        TextOrt += 1
                        Text.neuerText(TextBlaßen(TextOrt).GetSprechBlaße, ZusatzRand + TextRand + KOBildBreite, YOrt + 2, Nothing, True, 3)
                    End If
                Else
                    Frame = 0
                    Text.FertigGeschrieben()
                End If
            Case MouseButtons.Right
                MaxWarteZeit = 1
                Frame = 1
                Text.FertigGeschrieben()
        End Select
    End Sub
    Private Sub KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        If Now < ObjektKODialog.WarteZeit Then Exit Sub
        Select Case e.KeyCode
            Case My.Settings.Bestätigen
                If Text.IsGeschrieben Then
                    If TextOrt = TextBlaßen.Length - 1 Then
                        'Jetzt wird der Text beendet
                        MaxWarteZeit = 1
                    Else
                        TextOrt += 1
                        Text.neuerText(TextBlaßen(TextOrt).GetSprechBlaße, ZusatzRand + TextRand + KOBildBreite, YOrt + 2, Nothing, True, 3)
                    End If
                Else
                    Frame = 0
                    Text.FertigGeschrieben()
                End If
            Case My.Settings.Abrechen
                    MaxWarteZeit = 1
                    Frame = 1
                    Text.FertigGeschrieben()
        End Select
    End Sub

    Public Sub RemoveHandles()
        Text.Text = New String() {}
        RemoveHandler Hauptmenü.MainMenü.MalPanel.MouseDown, AddressOf MouseDown
        RemoveHandler Hauptmenü.MainMenü.KeyDown, AddressOf KeyDown
    End Sub
    Public Sub AddHandles()
        AddHandler Hauptmenü.MainMenü.MalPanel.MouseDown, AddressOf MouseDown
        AddHandler Hauptmenü.MainMenü.MalPanel.KeyDown, AddressOf KeyDown
    End Sub
End Class
''' <summary>
''' Lässt einen oder mehre KO's reden beinhaltet ObjektKOTextZeile
''' </summary>
''' <remarks></remarks>
Public Class ObjektKODialog
    Public Shared DialogHintergrundsbild As Texture = Nothing
    Public Shared DialogHintergrundsbildBreite, DialogHintergrundsbildHöhe As Integer

    Enum NächsteAktionen
        Keine
        RundenEnde
    End Enum
    Shared KOTextZeilen As ObjektKOTextZeile
    Dim NächsteAktion As NächsteAktionen
    Dim vorigeAktion As ObjektSpielMenü.Spielmodi
    Public Shared AktuellerDialog As ObjektKODialog

    ''' <summary>
    ''' Wie lange am anfang des Dialoges gewartet werden soll, bis man ihn wegmachen kann. In ms.
    ''' </summary>
    ''' <remarks></remarks>
    Const WartezeitAnfang As Integer = 300
    Const WartezeitEnde As Integer = 100
    ''' <summary>
    ''' Der Zeitpunkt, ab dem wieder Eingaben erlaubt sind.
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared WarteZeit As Date = Nothing


    Structure KOText
        ''' <summary>
        ''' Erschafft so ein neuen Text.
        ''' </summary>
        ''' <param name="KOID">Die ID des KO's der angezeigt wird z.b. ANDY oder OLAF</param>
        ''' <param name="Text">Was der/diejenige sprechen soll.</param>
        ''' <param name="Spieler">von welchem Spieler der Text kommt. Beeinflusst die Hintergrundsfarbe (sonst eigentlich nichts)</param>
        ''' <param name="Gesichtsausdruck">Na was wohl?</param>
        ''' <param name="WarteZeit">am besten nichts</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal KOID As String, ByVal Text As String, ByVal Spieler As Integer, ByVal Gesichtsausdruck As ObjektKOTextZeile.KOGesichtsAusdruck, Optional ByVal WarteZeit As Integer = -1, Optional ByVal Musik As String = "", Optional ByVal DialogBild As String = "")
            Dim ID As Integer = 0
            For I = 0 To Objektverwalter.KOS.Length - 1
                If KOID.ToUpper = Objektverwalter.KOS(I).KOID.ToUpper Then
                    ID = I
                    Exit For
                End If
            Next
            Me.KOID = ID
            Me.Text = Text
            Me.Spieler = Spieler
            If WarteZeit = 0 Then 'Also kleiner 0, kann ich kaum glauben... Vielleicht sollte ich selbst eine optimale Wartezeit finden ;)
                Me.WarteZeit = getOptimaleWartezeit(Text)
            Else
                Me.WarteZeit = WarteZeit
            End If
            Me.Gesichtsausdruck = Gesichtsausdruck
            Me.DialogMusik = Musik
            Me.DialogBild = DialogBild
        End Sub
        Public Sub New(ByVal KOID As Integer, ByVal Text As String, ByVal Spieler As Integer, ByVal Gesichtsausdruck As ObjektKOTextZeile.KOGesichtsAusdruck, Optional ByVal WarteZeit As Integer = -1, Optional ByVal Musik As String = "", Optional ByVal DialogBild As String = "")
            Me.KOID = KOID
            Me.Text = Text
            Me.Spieler = Spieler
            If WarteZeit = 0 Then 'Also kleiner 0, kann ich kaum glauben... Vielleicht sollte ich selbst eine optimale Wartezeit finden ;)
                Me.WarteZeit = getOptimaleWartezeit(Text)
            Else
                Me.WarteZeit = WarteZeit
            End If
            Me.Gesichtsausdruck = Gesichtsausdruck
            Me.DialogMusik = Musik
            Me.DialogBild = DialogBild
        End Sub
        Public KOID As Integer
        Public Text As String
        Public Spieler As Integer
        Public WarteZeit As Integer
        Public Gesichtsausdruck As ObjektKOTextZeile.KOGesichtsAusdruck
        Public DialogMusik, DialogBild As String
    End Structure
    ''' <summary>
    ''' Genau die Parameter, mit denen Man das neue Sprechen aufruft, können hier zwischengespeichert werden.
    ''' </summary>
    ''' <remarks></remarks>
    Structure KOTexteVorrat
        Public KOTexte() As KOText
        Public Y As Integer
        Public NächsteAktion As NächsteAktionen
        Sub New(ByVal KOTexte() As KOText, Optional ByVal Y As Integer = -1, Optional ByVal NächsteAktion As NächsteAktionen = NächsteAktionen.Keine)
            Me.KOTexte = KOTexte
            Me.Y = Y
            Me.NächsteAktion = NächsteAktion
        End Sub
    End Structure
    Shared KOTextVorrat() As KOTexteVorrat = {}

    Public Fertig As Boolean = False
    Dim KOTexte() As KOText = {}
    Dim YOrt As Integer
    Dim MomentanerText As Integer = 0
    ''' <summary>
    ''' Lässt einen KO etwas sprechen. HEY BITTE NICHT DAS PRIVATE WEGMACHEN lieber NeuerDialog aufrufen :)
    ''' </summary>
    ''' <param name="KOTexte"></param>
    ''' <param name="Y">Der Y wert, bei dem das ganze anfängt. Werte kleiner 0 Bildschirmhöhe - 50 </param>
    ''' <param name="NächsteAktion"></param>
    ''' <remarks></remarks>
    Private Sub New(ByVal KOTexte() As KOText, ByVal PreAktion As ObjektSpielMenü.Spielmodi, Optional ByVal Y As Integer = -1, Optional ByVal NächsteAktion As NächsteAktionen = NächsteAktionen.Keine, Optional ByVal FolgeDialog As Boolean = False)
        'PRIVATE   = RICHTIG (zumindest nicht unabsichtlich) wenn möglich bitte NeuerDialog aufrufen.
        If Not FolgeDialog Then
            If KOTextZeilen IsNot Nothing Then
                KOTextZeilen.AddHandles()
            End If
            WarteZeit = Now.AddMilliseconds(WartezeitAnfang)
        ElseIf KOTextZeilen IsNot Nothing Then
            KOTextZeilen.AddHandles()
        End If
        vorigeAktion = PreAktion

        Me.NächsteAktion = NächsteAktion
        If Y < 0 Then
            Y = Hauptmenü.MainMenü.MalPanel.Height - 50
        End If
        YOrt = Y
        Me.KOTexte = KOTexte
        NächsterText()
    End Sub
    ''' <summary>
    ''' Erschafft einen neuen Dialog, außer wenn ein anderer gerade läuft. In dem Fall wird er in eine Warteschleife gestellt.
    ''' </summary>
    ''' <param name="KOTexte"></param>
    ''' <param name="Y"></param>
    ''' <param name="NächsteAktion"></param>
    ''' <remarks></remarks>
    Public Shared Sub NeuerDialog(ByVal KOTexte() As KOText, Optional ByVal Y As Integer = -1, Optional ByVal NächsteAktion As NächsteAktionen = NächsteAktionen.Keine)
        If Not Hauptmenü.Aufzeichnungsspulen Then
            Dim Sofort As Boolean = False
            Dim PreAktion As ObjektSpielMenü.Spielmodi
            SyncLock KOTextVorrat
                Select Case Hauptmenü.Formmodus
                    Case Hauptmenü.Formmodi.Spiel
                        Dim M As ObjektSpielMenü = Objektverwalter.Menü
                        If M.Spielmodus = ObjektSpielMenü.Spielmodi.KOSprechen Then
                            'Wir haben uns also mit dem Sprechen, beim sprechen unterbrochen...
                            'Dann warten wir lieber höflich bis der andere zu ende gesprochen hat :)
                            Array.Resize(KOTextVorrat, KOTextVorrat.Length + 1)
                            KOTextVorrat(KOTextVorrat.Length - 1) = New KOTexteVorrat(KOTexte, Y, NächsteAktion)
                        Else
                            'Wenn wir noch nicht beim Sprechen sind, dann können wir ja anfangen zu sprechen.
                            PreAktion = M.Spielmodus
                            M.Spielmodus = ObjektSpielMenü.Spielmodi.KOSprechen
                            Sofort = True
                        End If
                    Case Hauptmenü.Formmodi.LandkartenAuswahlKAMP
                        If KOTextVorrat Is Nothing And AktuellerDialog Is Nothing Then
                            Sofort = True
                        ElseIf KOTextVorrat.Length = 0 And AktuellerDialog Is Nothing Then
                            Sofort = True
                        Else
                            Array.Resize(KOTextVorrat, KOTextVorrat.Length + 1)
                            KOTextVorrat(KOTextVorrat.Length - 1) = New KOTexteVorrat(KOTexte, Y, NächsteAktion)
                        End If
                End Select
            End SyncLock
            If Sofort Then 'Der Boolean ist nur da, weil ich das aktuellerDialog=... NEW ... nicht mit SyncLock machen wollte.
                AktuellerDialog = New ObjektKODialog(KOTexte, PreAktion, Y, NächsteAktion)
            End If
        Else
            Select Case NächsteAktion
                Case NächsteAktionen.RundenEnde
                    Objektverwalter.Spielfeld.RundenEnde()
            End Select
        End If
    End Sub

    Public Shared Function getOptimaleWartezeit(ByVal s As String) As Integer
        'Das optimal ist natürlich übertrieben, allerdings sicherlich besser als eine Konstante für egal welchen Text
        Dim i As Integer
        Dim c As Single = 0.8#
        'Meine Regeln:
        '1.) Generell gilt im Schnitt braucht man eine bestimmte Geschwindigkeit für jeden Buchstaben.
        '2.) Je schneller der Text fließt desto kürzer die warteZeit
        i = s.Length * c / My.Settings.Textfließgeschwindigkeit
        '3.) Eine Mindestzeit sollte natürlich trotzdem dabeisein :)
        If i < 10 Then i = 10
        If i > 50 Then i = 50
        '4.) Die Schrift erscheint ja eh mit einer Fließgeschwindigkeit und übertreiben sollte man es nicht :)
        'Damit ich diese mysteriöse Konstante c besser rauskrieg, protokollier ich's besser mal
        'Console.WriteLine("Eine Optimale Textfließgeschwindigkeit bei """ + s + """(" + s.Length.ToString + ") ist: " + i.ToString)
        Return i
    End Function


    Public Sub NächsterText()
        Dim mu As String = KOTexte(MomentanerText).DialogMusik
        If Not mu.Trim.ToLower = "" Then
            If mu.Trim.ToLower = "Default".ToLower Then
                'Standard wiederherstellen
                Hauptmenü.MusikZufällig()
            Else
                'eine neue Musik
                Hauptmenü.MusikauswählenCustom(mu)
            End If
        End If
        Dim Bild As String = KOTexte(MomentanerText).DialogBild
        If Not Bild.Trim.ToLower = "" Then
            If Bild.Trim.ToLower = "default" Then
                'Standard wiederherstellen... also einfach kein Bild!
                DialogHintergrundsbild = Nothing
                VideoKlasse.Abbrechen()
            Else
                'eingenes Bild Anzeigen..

                Dim Pfad As String = Bild.ToLower.Trim
                Dim Datei As String = ""
                If Pfad(1) = ":" Then
                    'Ein absoluter Pfad, das ist zwar eigentlich nicht gut, aber mal schauen, ob wir dort Bilder finden..
                    If My.Computer.FileSystem.FileExists(Pfad) Then
                        Datei = Pfad
                    End If
                Else
                    If Pfad.StartsWith("\Resources\".ToLower) Or Pfad.StartsWith("Resources\".ToLower) Then
                        'Ein pfad relativ zu den resourcen.
                        If My.Computer.FileSystem.FileExists(My.Settings.Resourcenpfad + Pfad.Replace("\Resources\".ToLower, "").Replace("Resources\".ToLower, "")) Then
                            Datei = My.Settings.Resourcenpfad + Pfad.Replace("\Resources\".ToLower, "").Replace("Resources\".ToLower, "")
                        End If
                    Else
                        'ich nehme an das Bild befindet sich ordnungsgemäß..
                        If My.Computer.FileSystem.FileExists(My.Settings.Resourcenpfad + "!Custom\Pictures\" + Pfad) Then
                            Datei = My.Settings.Resourcenpfad + "!Custom\Pictures\" + Pfad
                        Else
                            'Die datei gibt es nicht....
                            If My.Computer.FileSystem.FileExists(My.Settings.Resourcenpfad + Pfad) Then
                                'nur falsch eingeordnet, aber immerhin gibt es überhaupt etwas zu sehen.
                                Datei = My.Settings.Resourcenpfad + Pfad
                            Else
                                Console.WriteLine("konnte folgendes Bild nicht finden: " + Pfad)
                            End If
                        End If
                    End If
                End If
                If Not Datei = "" Then
                    If Datei.ToLower.EndsWith(".avi") Then 'Theoretisch könnte man natürlich auch noch andere Video-Formate nehmen, die DirectX akzeptiert, aber ich glaube in dem Fall können wir drauf verzichten, oder nachträglich verändern..
                        'Oho, ein Video soll also nun abgespielt werden.
                        'Vollbild Video, oder mit Dialog?
                        If 1 = 0 Then
                            'Vollbild
                            VideoKlasse.Neu(Datei, Hauptmenü.MainMenü.pVideo, True, True)
                        Else
                            Hauptmenü.MainMenü.pVideo.Height = Hauptmenü.MalPanel.Height - 50
                            Hauptmenü.MainMenü.pVideo.Width = Hauptmenü.MalPanel.Width
                            'Nicht Vollbild
                            VideoKlasse.Neu(Datei, Hauptmenü.MainMenü.pVideo, False, True)
                        End If
                    Else 'Vermutlich ein normales Bild
                        'Es wurde also schlussendlich etwas gefunden, was nun angezeigt werden kann.
                        Dim Bmp As Bitmap = Image.FromFile(Datei)
                        DialogHintergrundsbild = Grafikengine.LoadTexture(Bmp)
                        DialogHintergrundsbildBreite = Bmp.Width
                        DialogHintergrundsbildHöhe = Bmp.Height
                    End If
                End If
            End If
        End If
        If KOTexte(MomentanerText).Text.ToLower.Trim.StartsWith("%Language%".ToLower) Then
            'Das übersetzen wir am besten erstmal..
            KOTexte(MomentanerText).Text = DialogTextSprachKonverter.SprachKonvIni.getText(KOTexte(MomentanerText).Text.Split("%")(2))
        End If
        If KOTextZeilen Is Nothing Then
            KOTextZeilen = New ObjektKOTextZeile(KOTexte(MomentanerText).KOID, KOTexte(MomentanerText).Text, KOTexte(MomentanerText).Gesichtsausdruck, YOrt, KOTexte(MomentanerText).WarteZeit, KOTexte(MomentanerText).Spieler)
        Else
            KOTextZeilen.Laden(KOTexte(MomentanerText).KOID, KOTexte(MomentanerText).Text, KOTexte(MomentanerText).Gesichtsausdruck, YOrt, KOTexte(MomentanerText).WarteZeit, KOTexte(MomentanerText).Spieler)
        End If
        MomentanerText += 1
    End Sub

    Public Function Malen() As Boolean
        If KOTextZeilen.Malen() = True Then
            If MomentanerText >= KOTexte.Length Then
                Fertig = True
            Else
                NächsterText()
            End If
        End If
        Return Fertig
    End Function

    Public Sub Löschen()
        Select Case NächsteAktion
            Case NächsteAktionen.RundenEnde
                Objektverwalter.Spielfeld.RundenEnde()
                Hauptmenü.CursorPlazieren(Objektverwalter.Spielfeld.AktuelleEinheitPosition.X * Hauptmenü.Feldbreite, Objektverwalter.Spielfeld.AktuelleEinheitPosition.Y * Hauptmenü.Feldbreite)
        End Select
        Dim nächsterDialog As KOTexteVorrat = Nothing
        Dim nachfolgeDialog As Boolean = False
        Select Case Hauptmenü.Formmodus
            Case Hauptmenü.Formmodi.Spiel
                Dim M As ObjektSpielMenü = Objektverwalter.Menü
                SyncLock KOTextVorrat
                    If KOTextVorrat.Length > 0 Then
                        'Wir haben solange gereden, dass inzwischen auch andere was sagen wollen. Geben wir doch unserem Nachfolger das Wort.
                        nächsterDialog = KOTextVorrat(0)
                        For i = 0 To KOTextVorrat.Length - 2
                            KOTextVorrat(i) = KOTextVorrat(i + 1)
                        Next
                        Array.Resize(KOTextVorrat, KOTextVorrat.Length - 1)
                        nachfolgeDialog = True
                    Else
                        'Jetz wird wieder die vorige Aktion gemacht (vor dem Dialog), aber was, wenn sich zwischenzeitlich die Aktion geändert hat?
                        If M.Spielmodus = ObjektSpielMenü.Spielmodi.KOSprechen Then
                            If vorigeAktion = ObjektSpielMenü.Spielmodi.TagZuTagAnzeige Then
                                M.Spielmodus = ObjektSpielMenü.Spielmodi.Nichts
                            Else
                                M.Spielmodus = vorigeAktion
                            End If
                        Else
                            '  M.Spielmodus = M.Spielmodus
                        End If
                        AktuellerDialog = Nothing
                    End If
                End SyncLock
            Case Hauptmenü.Formmodi.LandkartenAuswahlKAMP
                SyncLock KOTextVorrat
                    If KOTextVorrat.Length > 0 Then
                        'Wir haben solange gereden, dass inzwischen auch andere was sagen wollen. Geben wir doch unserem Nachfolger das Wort.
                        nächsterDialog = KOTextVorrat(0)
                        For i = 0 To KOTextVorrat.Length - 2
                            KOTextVorrat(i) = KOTextVorrat(i + 1)
                        Next
                        Array.Resize(KOTextVorrat, KOTextVorrat.Length - 1)
                        nachfolgeDialog = True
                    Else
                        AktuellerDialog = Nothing
                    End If
                End SyncLock
        End Select
        If nachfolgeDialog Then
            AktuellerDialog = New ObjektKODialog(nächsterDialog.KOTexte, vorigeAktion, nächsterDialog.Y, nächsterDialog.NächsteAktion, True)
        Else
            WarteZeit = Now.AddMilliseconds(WartezeitEnde)
            VideoKlasse.Abbrechen()
        End If
        'M.Spielmodus = ObjektSpielMenü.Spielmodi.Nichts
    End Sub

    Public Shared Function EingabenAngenommen() As Boolean
        If Now < WarteZeit Then Return True
        Return False
    End Function
    Public Shared Sub ChangeWindowSize(ByVal PosChange As Point)
        If AktuellerDialog IsNot Nothing Then
            If AktuellerDialog.YOrt > 0 Then
                AktuellerDialog.YOrt += PosChange.Y
            End If
        End If
        If KOTextZeilen IsNot Nothing Then
            If KOTextZeilen.GetYOrt > 0 Then
                KOTextZeilen.ChangeYOrt(PosChange.Y)
            End If
        End If
    End Sub
End Class



Public Class VideoKlasse
    Shared _Video As Video
    Shared Vollbild As Boolean
    Shared VideoHalter As Control
    Public Shared Sub Neu(ByVal Datei As String, ByVal VideoPanel As Control, ByVal bVollbild As Boolean, ByVal Autostart As Boolean)
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then _Video.Dispose()
        End If
        VideoHalter = VideoPanel
        Dim S As New Rectangle(VideoPanel.Location, VideoPanel.Size)
        VideoHalter.Visible = True

        If Not My.Settings.MusikSound Then
            Vollbild = False
        Else
            Vollbild = bVollbild
        End If

        If My.Computer.FileSystem.FileExists(Datei) Then
            _Video = New Video(Datei)
        End If
        _Video.Owner = VideoHalter
        If Not Vollbild Then
            _Video.Owner.Location = S.Location
            _Video.Owner.Size = S.Size
        End If
        If Autostart Then
            Play()
        End If
    End Sub

    Public Shared Sub Play()
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                If Not _Video.Playing Then
                    If Not Vollbild Then
                        If (Not My.Settings.TaskAnzeigenModus = TaskleistenAnzeige.Taskleiste) Or (Not My.Settings.MusikSound) Then
                            'Hier will man vermutlich auch im Film keine Musik hören!
                            Try
                                _Video.Audio.Volume = -10000
                            Catch
                            End Try
                        End If
                    End If
                    _Video.Fullscreen = Vollbild
                    _Video.Play()
                    Try
                        _Video.Fullscreen = Vollbild
                    Catch
                    End Try
                End If
            End If
        End If
    End Sub
    Public Shared Sub Pause()
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                If Not _Video.Paused Then
                    _Video.Pause()
                End If
            End If
        End If
    End Sub
    Public Shared Sub Stopp()
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                If Not _Video.Stopped Then
                    _Video.Stop()
                End If
            End If
        End If
    End Sub
    Public Shared Sub Abbrechen()
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                _Video.Dispose()
                VideoHalter.Visible = False
            End If
        End If
    End Sub

    Private Shared Sub CheckBeschäftigt()
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                If _Video.CurrentPosition = _Video.Duration Then
                    Abbrechen()
                End If
            End If
        End If
    End Sub

    ''' <summary>
    ''' Gibt zurück, ob generell gerade ein Video abgespielt wird, egal ob im Fenster- oder Vollbild modus.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function BeschäftigtAbspielen()
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                If Not Vollbild = _Video.Fullscreen Then _Video.Fullscreen = Vollbild
                CheckBeschäftigt()
                If Not _Video.Disposed Then Return True
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Gibt True, wenn wir etwas im Vollbild abspielen
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function Beschäftigt() As Boolean
        If _Video IsNot Nothing Then
            If Not _Video.Disposed Then
                If Not Vollbild = _Video.Fullscreen Then _Video.Fullscreen = Vollbild
                CheckBeschäftigt()
                If Not _Video.Disposed Then Return Vollbild
            End If
        End If
        Return False
    End Function

End Class